# vim:ts=4:sw=4:noet:
""" Class info panel """

import wx
from c.ui.wxw.widgets.checkedentry import CheckedEntry
from c.base.support import CoreException
import re

class NewIvarDialog(wx.Dialog):

	def __init__(self, parent, supername="", clsname=""):
		wx.Dialog.__init__(self, parent, -1, "New Instance Variable")
		self.mw = parent

		self.textctrl = CheckedEntry(self, self.doCheck, self.doDone, clsname)
		
		self.ok = wx.Button(self, wx.ID_OK, "OK")
		self.ok.Enable(False)
		cancel = wx.Button(self, wx.ID_CANCEL, "Cancel")
		
		dlgsizer = wx.BoxSizer(wx.VERTICAL)
		dlgsizer.Add(self.textctrl, 1, wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, 10)
		
		btnsizer = wx.StdDialogButtonSizer()
		btnsizer.AddButton(self.ok)
		btnsizer.AddButton(cancel)
		btnsizer.Realize()
		
		dlgsizer.Add(btnsizer, 0, wx.ALL | wx.ALIGN_RIGHT, 10)
		
		self.SetSizer(dlgsizer)

		self.Fit()
		self.Centre()

	def GetValue(self):
		return self.textctrl.GetValue()

	def doCheck(self, val):
		if val in [x.strip(" -") for x in self.mw.items]:
			self.ok.Enable(False)
			return False, "Instance name already exists"
		if val=="":
			self.ok.Enable(False)
			return False, "Instance name must be non-empty"
		if not re.match("^[a-zA-Z][a-zA-Z0-9]*$", val):
			self.ok.Enable(False)
			return False, "Invalid instance name"
		self.ok.Enable(True)
		return True, ""

	def doDone(self):
		if self.ok.IsEnabled():
			self.EndModal(wx.ID_OK)

class VarListPanel(wx.Panel):
	def __init__(self, parent, mw): #, obj):
		wx.Panel.__init__(self, parent)
		self.mw = mw
		self.obj = None
		self.items = []
		self.editable = True
		psizer = wx.BoxSizer(wx.VERTICAL)
		varListId = wx.NewId()
		self.varList = wx.ListBox(self, varListId, choices=self.items)
		self.varList.Bind(wx.EVT_LISTBOX, self.onListBox, id=varListId)

		psizer.Add(self.varList, 1, wx.ALL|wx.EXPAND, 10)
	
		addId = wx.NewId()
		self.add = wx.Button(self, addId, "Add new ...")
		self.add.SetDefault()
		self.Bind(wx.EVT_BUTTON, self.onAdd, id=addId)
		remId = wx.NewId()
		self.remove = wx.Button(self, remId, "Remove")
		self.remove.Enable(False)
		self.Bind(wx.EVT_BUTTON, self.onRemove, id=remId)
		
		btnsizer = wx.BoxSizer(wx.HORIZONTAL)
		btnsizer.Add(self.add, 0, wx.RIGHT, 10)
		btnsizer.Add(self.remove)
		
		psizer.Add(btnsizer, 0, wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.ALIGN_RIGHT, 10)
		psizer.Fit(self)
		self.SetSizer(psizer)
		self.Fit()
		self.Layout()

	def setEditable(self, editable):
		self.editable = editable
		if editable:
			self.add.Enable(True)
		else:
			self.remove.Enable(False)
			self.add.Enable(False)

	def setObject(self, obj):
		self.obj = obj
		self.items = obj.getAllIvars()
		for i in range(len(self.items)-len(obj.instanceNames)):
			self.items[i] = "- "+self.items[i]
		self.varList.Clear()
		self.varList.AppendItems(self.items)
	
	def onListBox(self, event):
		sel = self.varList.GetSelection()
		if (sel == wx.NOT_FOUND or 
				sel < (len(self.obj.getAllIvars())-len(self.obj.instanceNames)) or 
				not self.editable):
			self.remove.Enable(False)
		else:
			self.remove.Enable(True)

	def onAdd(self, event):
		dialog = NewIvarDialog(self)
		res = dialog.ShowModal()
		if res == wx.ID_OK:
			ivar = dialog.GetValue()
			self.varList.AppendAndEnsureVisible(ivar)
			self.items.append(ivar)
			self.obj.addIvar(ivar)

	def onRemove(self, event):
		sel = self.varList.GetSelection()
		if sel != wx.NOT_FOUND:
			self.varList.Delete(sel)
			self.obj.removeIvar(self.items[sel])

class ClassPanel(wx.Panel):

	def __init__(self, parent, mc):
		wx.Panel.__init__(self, parent, -1)
		if wx.Platform=="__WXMAC__":
			self.SetBackgroundColour(wx.Color(232,232,232))
		self.mc = mc
		vbox = wx.BoxSizer(wx.VERTICAL)

		self.lblHdrName = wx.StaticText(self, -1, "Name")
		self.lblName = wx.StaticText(self, -1, "")
		self.lblHdrSuper = wx.StaticText(self, -1, "Superclass")
		self.lblSuper = wx.StaticText(self, -1, "")

		self.static_line_1 = wx.StaticLine(self, -1)
		self.varsNotebook = wx.Notebook(self, -1)

		self.ivarPanel = VarListPanel(self.varsNotebook, self)
		self.varsNotebook.AddPage(self.ivarPanel, "Instance")
		self.cvarPanel = VarListPanel(self.varsNotebook, self)
		self.varsNotebook.AddPage(self.cvarPanel, "Class")
		
		ft = self.lblName.GetFont()
		newft = wx.Font(ft.GetPointSize(), wx.DECORATIVE, wx.NORMAL, wx.BOLD, 0, ft.GetFaceName())

		self.lblHdrName.SetFont(newft)
		self.lblHdrSuper.SetFont(newft)

		grid_sizer_1 = wx.FlexGridSizer(2, 2, 5, 5)
		grid_sizer_1.Add(self.lblHdrName, 0, wx.ALIGN_RIGHT, 0)
		grid_sizer_1.Add(self.lblName, 0, wx.EXPAND, 0)
		grid_sizer_1.Add(self.lblHdrSuper, 0, wx.ALIGN_RIGHT, 0)
		grid_sizer_1.Add(self.lblSuper, 0, wx.EXPAND, 0)
		vbox.Add(grid_sizer_1, 0, wx.ALL|wx.EXPAND, 5)
		vbox.Add(self.static_line_1, 0, wx.EXPAND, 0)
		vbox.Add(self.varsNotebook, 1, wx.ALL|wx.EXPAND, 5)
		self.SetSizer(vbox)
		vbox.Fit(self)
		self.Layout()		
		self.SetMinSize(vbox.GetMinSize())
		self.Fit()

	def setObject(self, obj, inLibrary):
		self.lblName.SetLabel(obj.name)
		supername = "nil"
		if obj.parent != self.mc.mem.nilObject:
			supername = obj.parent.name
		self.lblSuper.SetLabel(supername)
		self.ivarPanel.setObject(obj)
		self.cvarPanel.setObject(obj.cls)
		
		editable = (not inLibrary) or self.mc.isLibraryEditable()
		self.ivarPanel.setEditable(editable)
		self.cvarPanel.setEditable(editable)

